package com.hellohoper.script.config.engine.task;

import com.hellohoper.script.config.admin.app.dao.pojo.ScriptConfig;
import com.hellohoper.script.config.api.feign.ScriptConfigFeign;
import com.hellohoper.script.config.engine.container.ScriptContainer;
import com.hellohoper.script.config.engine.container.file.ScriptFileOptionService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.netflix.ribbon.RibbonClientHttpRequestFactory;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.client.RestTemplate;

import java.io.IOException;
import java.util.List;

/**
 * 脚本内容初始化+定时刷新
 * Created by hk on 12/14/16.
 */
@Configuration
public class InitScriptProcessor implements InitializingBean {

    private static final Logger LOGGER = LoggerFactory.getLogger(InitScriptProcessor.class);
    @Autowired
    private ScriptContainer scriptContainer;

    @Autowired
    private ScriptConfigFeign scriptConfigFeign;

    @Autowired
    private Environment environment;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private DiscoveryClient discoveryClient;

    @Autowired
    private ScriptFileOptionService fileOptionService;

    @Bean
    public RestTemplate restTemplate(ClientHttpRequestFactory clientHttpRequestFactory) {
        return new RestTemplate(clientHttpRequestFactory);
    }

    @Bean
    public ClientHttpRequestFactory clientHttpRequestFactory(SpringClientFactory clientFactory) {
        RibbonClientHttpRequestFactory clientHttpRequestFactory = new RibbonClientHttpRequestFactory(clientFactory);
        return clientHttpRequestFactory;
    }

    // 定时任务每小时刷新
    @Scheduled(cron = "0 * */1 * * ?")
    public void loadConfigFromFeign() throws Exception {
        // 获得appName
        String appName = environment.getProperty("spring.application.name");
        // 先调动服务注册中心，初始化URL
        discoveryClient.getInstances("SCRIPT-CONFIG-API-APP");

        // ResponseEntity<List> forEntity = restTemplate.getForEntity("http://SCRIPT-CONFIG-API-APP//config/api/searchList?appName={1}", List.class, appName);
        List<ScriptConfig> scriptConfigs = scriptConfigFeign.searchConfig(appName);
        if (scriptConfigs != null && scriptConfigs.size() > 0) {
            // 保存到本地文件
            fileOptionService.saveScriptFile(appName, scriptConfigs);
            // 添加到脚本容器中
            scriptConfigs.forEach(scriptConfig -> scriptContainer.addScript(scriptConfig.getAppName(),
                    scriptConfig.getScriptName(), scriptConfig.getScriptContent()));
        }
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        try {
            // 调用接口获取
            loadConfigFromFeign();
        } catch (Exception e) {
            // 本地配置文件获取
            loadConfigFromFile();
            LOGGER.error("获得脚本内容是失败！", e);
        }
    }

    private void loadConfigFromFile() throws IOException {
        // 获得appName
        String appName = environment.getProperty("spring.application.name");
        List<ScriptConfig> scriptConfigs = fileOptionService.loadScriptConfig(appName);
        if (scriptConfigs != null && scriptConfigs.size() > 0) {
            scriptConfigs.forEach(scriptConfig -> scriptContainer.addScript(scriptConfig.getAppName(),
                    scriptConfig.getScriptName(), scriptConfig.getScriptContent()));
        }
    }
}
